package com.be.beadmin.system.impl.ProductMaterialServiceImpl;

import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.design.dto.output.ProductBomOverviewEx;
import com.be.beadmin.design.entity.*;
import com.be.beadmin.design.entity.Process;
import com.be.beadmin.design.mapper.ProductBomOverviewMapperEx;
import com.be.beadmin.design.repository.BopInfoRepository;
import com.be.beadmin.design.repository.ProductBomOverviewRepository;
import com.be.beadmin.design.repository.ProductDrawingInfoRepository;
import com.be.beadmin.design.repository.StandFileInfoRepository;
import com.be.beadmin.design.service.ProcessService;
import com.be.beadmin.design.service.StandProductProcessInfoService;
import com.be.beadmin.design.service.StandProductService;
import com.be.beadmin.material.entity.*;
import com.be.beadmin.material.repository.*;
import com.be.beadmin.material.service.PickingDetailsService;
import com.be.beadmin.material.service.PickingOverViewService;
import com.be.beadmin.material.service.PickingReccieveDetailsService;
import com.be.beadmin.material.service.PickingTaskService;
import com.be.beadmin.product.dto.output.ProductManufactExecInfoEx;
import com.be.beadmin.product.entity.ProductManufactInfor;
import com.be.beadmin.product.entity.WorkOrderInfor;
import com.be.beadmin.product.repository.ProductManufactInforRepository;
import com.be.beadmin.product.repository.WorkOrderInforRepository;
import com.be.beadmin.product.service.ProductManufactInforService;
import com.be.beadmin.product.service.WorkOrderInforService;
import com.be.beadmin.project.entity.*;
import com.be.beadmin.project.repository.*;
import com.be.beadmin.project.service.BatchPlanService;
import com.be.beadmin.project.service.InfoService;
import com.be.beadmin.quality.entity.InspectionTask;
import com.be.beadmin.quality.repository.InspectionTaskRepository;
import com.be.beadmin.quality.service.ProductQualityService;
import com.be.beadmin.service.entity.NotifyInfo;
import com.be.beadmin.service.repository.NotifyInfoRepository;
import com.be.beadmin.service.service.NotifyTemplateInfoService;
import com.be.beadmin.service.service.SerialNumberService;
import com.be.beadmin.service.task.BaseTask;
import com.be.beadmin.service.task.TaskThreadPool;
import com.be.beadmin.service.util.DateUtil;
import com.be.beadmin.system.service.ProductMaterialService.PickingReccieveDetailsPmService;
import com.be.beadmin.system.service.ProductMaterialService.WorkOrderInforPmService;
import com.be.beadmin.system.service.ProductQualityService.ProductManufactInforPqService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Consumer;

/**
 * @Description:
 * @author: Jiaming Zheng
 * @Date: Create in 15:22 2023/6/20
 * @Modified By:
 **/
@Service
public class WorkOrderInforPmServiceImpl implements WorkOrderInforPmService {


    @Autowired
    private ProductQualityService productQualityService;
    @Autowired
    private BatchPlanRepository batchPlanRepository;

    @Autowired
    private TaskThreadPool taskThreadPool;
    @Autowired
    private BatchPlanService batchPlanService;
    @Autowired
    private MasterPlanRepository masterPlanRepository;
    @Autowired
    private PickingOverViewService pickingOverViewService;
    @Autowired
    private PickingTaskService pickingTaskService;
    @Autowired
    private PurchaseOrderRepository purchaseOrderRepository;

    @Autowired
    private PurchaseOrderDetailRepository purchaseOrderDetailRepository;

    @Autowired
    private PickingDetailsService pickingDetailsService;

    @Autowired
    private StandFileInfoRepository standFileInfoRepository;


    @Autowired
    private PickingReccieveDetailsPmService pickingReccieveDetailsPmService;

    @Autowired
    private PickingTaskRepository pickingTaskRepository;
    @Autowired
    private ProcessService processService;
    @Autowired
    private InspectionTaskRepository inspectionTaskRepository;

    @Autowired
    private StandProductService standProductService;
    @Autowired
    private StandProductProcessInfoService standProductProcessInfoService;
    @Autowired
    private PickingDetailsRepository pickingDetailsRepository;
    @Autowired
    private ProductDrawingInfoRepository productDrawingInfoRepository;
    @Autowired
    private ProductManufactInforPqService productManufactInforPqService;
    @Autowired
    private ProductManufactInforService productManufactInforService;
    @Autowired
    private ProductManufactInforRepository productManufactInforRepository;

    @Autowired
    private WorkOrderInforRepository workOrderInforRepository;
    @Autowired
    private BopInfoRepository bopInfoRepository;
    @Autowired
    private SerialNumberService serialNumberService;
//    @Autowired
//    private  workOrderInforPdService;

    @Autowired
    private BatchProductRepository batchProductRepository;
    @Autowired
    private ProductBomOverviewMapperEx productBomOverviewMapperEx;
    @Autowired
    private ProductBomOverviewRepository productBomOverviewRepository;
    @Autowired
    private WorkOrderInforService workOrderInforService;
    @Autowired
    private InfoRepository infoRepository;

    @Autowired
    private MaterialShortageRepository materialShortageRepository;

    @Autowired
    private TeamInfoRepository teamInfoRepository;

    @Autowired
    private NotifyTemplateInfoService notifyTemplateInfoService;

    @Autowired
    private NotifyInfoRepository notifyInfoRepository;

    @Autowired
    private PlanStageRepository planStageRepository;


    @Transactional
    @Override
    public int releaseWorkOrderInfor(String workOrderId) {
        /**
         *         if (result == -1) return ResultModel.error(result,"工单已释放，请不要重复释放");
         *         if (result == -2) return ResultModel.error(result,"未找到该工单");
         *         if (result == -3) return ResultModel.success("计划没有调整过，工单已释放");
         *
         *
         */


        int flag = 0;
        WorkOrderInfor workOrderInfor = workOrderInforRepository.findWorkOrderInforByIdAndDelete(workOrderId,0);
        if (workOrderInfor == null) {
            throw new BeadminException("未找到该工单");
//            flag = -2;
//            return flag;
        }
//            throw new BeadminException("未找到该工单");
        if (workOrderInfor.getReleaseFlag() != 0) {
//            flag = -1;
//            return flag;
            throw new BeadminException("工单已释放，请不要重复释放");
        }
//        throw new BeadminException("工单已释放，请不要重复释放");

        // 1 校验单柜工序最晚结束时间是否晚于批次计划结束时间
//        boolean result = productManufactInforService.checkPlanDateOut(workOrderInfor);
//        if (!result) throw new BeadminException("加工结束时间超出订单结束时间");
        // 系统先向ERP发送物料下架请求，ERP返回成功再向物料模块下发分料任务，最后更新单柜订单释放标识
        // 2 首先下发分料任务
        /*
        后续完成
         */
        // 2.1 分料任务总览 PickingOverView
        pickingOverViewService.deliverPickingTask(workOrderInfor);
        // 2.2 生成分料任务 PickingTask
        pickingTaskService.deliverPickingTask(workOrderInfor);
//        pickingTaskRepository.findPickingTaskByIdAndDelete()
        // 2.3 分料任务详细内容 PickingDetails
        deliverPickingDetails(workOrderInfor);
        // 2.4 收料任务详单 PickingReccieveDetails
        pickingReccieveDetailsPmService.reccieveDetails(workOrderInfor);
        // 3 校验计划是否调整过，没有需提醒，但是不强制要求。
        if (workOrderInfor.getPlanEditFlag() == 0) flag =-3; //没调整， 需提醒
//        // 4 校验图纸是否打印过，没有需提醒，但是不强制要求。
//        List<ProductDrawingInfo> productDrawingInfos = productDrawingInfoRepository.findProductDrawingInfosByProductCodeAndPrintFlagAndDelete(workOrderInfor.getBatchProductCode(),0,0);
//        if (productDrawingInfos != null ) flag =  -4; //没打印过， 需提醒
        // 5 校验计划生产时间段内产能是否超过负荷，超过需要提醒，但是不强制要求。
        /*
        后续完成
         */
        workOrderInfor.setReleaseFlag(1);
        workOrderInfor.setReleaseTime(new Date());
        // 柜体的设计文件是否齐套
        setKitting(workOrderInfor);
        workOrderInfor=workOrderInforRepository.save(workOrderInfor);

        //-------------------------------------------------------------------
        //能够成功释放
        // 生产经理 发送 工单释放 通知给  项目成员+生产组长
        NotifyInfo notifyInfo =new NotifyInfo();
        notifyInfo.setModuleName("生产制造");
        notifyInfo.setFuncName("工单释放");

        String wo=workOrderInfor.getWo();

        notifyInfo.setNotifyDesc("工单号["+wo+"]---工单已被释放");
        notifyInfo.setNotifyType("通知");

        String infoId = workOrderInfor.getInfoId();
        Info info = infoRepository.findInfoByIdAndDelete(infoId,0);
        if(info == null) return flag;
        String teamId = info.getTeamId();
        if(teamId==null) return flag;
        List<TeamInfo> teamInfoList = teamInfoRepository.findTeamInfoByTeamIdAndDelete(teamId,0);
        TeamInfo projectManager =  teamInfoRepository.findTeamInfoByTeamIdAndCategoryAndDelete(teamId,"生产经理",0);
        String senderName = "-";
        String senderId="-";
        if(projectManager!=null){
            if(projectManager.getUserName()!=null){
                senderName = projectManager.getUserName();
            }
            if(projectManager.getUserId()!=null){
                senderId = projectManager.getUserId();
            }
        }
        notifyInfo.setSenderName(senderName);
        notifyInfo.setSenderId(senderId);
        notifyInfo.setSendTime(workOrderInfor.getUpdateTime());
        notifyInfo = notifyInfoRepository.save(notifyInfo);

        Set<String> st =new HashSet<>();
        for (TeamInfo teamInfo:teamInfoList){
            String receiver = teamInfo.getUserName();
            if(receiver!=null&&!st.contains(receiver)){
                st.add(receiver);
                notifyTemplateInfoService.sendNotify(notifyInfo,-1,receiver,teamInfo.getUserId());
            }
        }
        //放最后
        //--------------------------------
        return flag;
    }

    private void setKitting(WorkOrderInfor workOrderInfor) { // 找他的文件，， 去哪里找啊 。。。。
        BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(workOrderInfor.getBatchProductId(), 0);
        workOrderInfor.setIsFileKitting(0);
        if (batchProduct.getIsStandard()==1) {
            for (ProductDrawingInfo productDrawingInfo : productDrawingInfoRepository.findProductDrawingInfosByProductCodeAndDelete(workOrderInfor.getBatchProductCode(), 0)) {
//                StandFileInfo standFileInfo = standFileInfoRepository.findStandFileInfoByFileCode(productDrawingInfo.getDrawingCode());
                if (ObjectUtil.equal(productDrawingInfo.getCategory(),"电气原理图")){
                    workOrderInfor.setIsFileKitting(1);
                }
            }
        } else {
            workOrderInfor.setIsFileKitting(1);
        }

    }

    /**
     * 获取BOM信息
     *
     * @param workOrderInfoId
     * @return
     */
    @Override
    public List<ProductBomOverviewEx> getBomOverview(String workOrderInfoId) {
        WorkOrderInfor workOrderInfor = workOrderInforRepository.findWorkOrderInforByIdAndDelete(workOrderInfoId, 0);
//        System.out.println("batchProductId"+batchProductId);
        BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(workOrderInfor.getBatchProductId(),0);
//        System.out.println("batchProduct"+batchProduct);

        List<ProductBomOverview> productBomOverviews = productBomOverviewRepository.findProductBomOverviewsByProductCodeAndDelete(batchProduct.getProductCode(),0);
        List<String> strings = productBomOverviewRepository.findMaterialCodeByProductCodeAndDelete(batchProduct.getProductCode(), 0);
        List<ProductBomOverviewEx> productBomOverviewExes = new ArrayList<>();
        strings.forEach(
                new Consumer<String>() {
                    @Override
                    public void accept(String s) {

                        List<ProductBomOverview> productBomOverviews1 = productBomOverviewRepository.findProductBomOverviewsByProductCodeAndMaterialCodeAndDeleteOrderByVersionDesc(batchProduct.getProductCode(), s, 0);
                        if (productBomOverviews1.size()!=0) {
                            ProductBomOverviewEx productBomOverviewEx = productBomOverviewMapperEx.toEntity(productBomOverviews1.get(0));

                            if (workOrderInfor.getReleaseFlag() != 0) { // 未释放，则没有分料任务，所有的物料的已发数量肯定都是0
                                //PickingDetails pickingDetails = pickingDetailsRepository.findPickingDetailByMaterialCodeAndProductCodeAndDelete(productBomOverviewEx.getMaterialCode(), batchProduct.getWoId(), 0);
                                PickingTask pickingTask = pickingTaskRepository.findPickingTaskByProjectNameAndProductCodeAndDelete(batchProduct.getProjectName(), batchProduct.getProductCode(), 0);
                                PickingDetails pickingDetails = pickingDetailsRepository.findPickingDetailsByMaterialCodeAndPickingTaskCodeAndDelete(productBomOverviewEx.getMaterialCode(), pickingTask.getPickingTaskCode(), 0);
                                if (pickingDetails != null) {
//                                    System.out.println("=========================================");
//                                    System.out.println(pickingDetails.toString());
                                    productBomOverviewEx.setOutboundQty(pickingDetails.getOutboundQty());
                                    productBomOverviewEx.setNotIssuedQty(pickingDetails.getNotIssuedQty());
                                }
                            }else{
                                productBomOverviewEx.setOutboundQty(0);
                                productBomOverviewEx.setNotIssuedQty(productBomOverviewEx.getMaterialQty());
                            }
                            //productBomOverviewEx.setNotIssuedQty(pickingDetails.getNo);
                            productBomOverviewExes.add(productBomOverviewEx);
                        }

                    }
                }
        );

//        if (workOrderInfor.getReleaseFlag() == 0) { // 未释放，则没有分料任务，所有的物料的已发数量肯定都是0
//            return productBomOverviewMapperEx.toEntity(productBomOverviews);
//        } else { // 已释放，产生分料任务后， 物料就开始有已发数量了
//
//
//            productBomOverviews.forEach(new Consumer<ProductBomOverview>() {
//                @Override
//                public void accept(ProductBomOverview productBomOverview) {
//                    PickingDetails pickingDetails = pickingDetailsRepository.findPickingDetailByMaterialCodeAndProductCodeAndDelete(productBomOverview.getMaterialCode(), batchProduct.getProductCode(), 0);
//                    if (pickingDetails == null) {
//                        pickingDetails = new PickingDetails();
//                    }
//                    ProductBomOverviewEx productBomOverviewEx = productBomOverviewMapperEx.toEntity(productBomOverview);
//
//                    productBomOverviewEx.setOutboundQty(pickingDetails.getOutboundQty());
//                    productBomOverviewEx.setNotIssuedQty(productBomOverviewEx.getMaterialQty()-productBomOverviewEx.getOutboundQty());
//                    productBomOverviewExes.add(productBomOverviewEx);
////                    return productBomOverviewEx;
//                }
//            });

            return productBomOverviewExes;

//        }
//        System.out.println("productBomOverviews"+productBomOverviews);

    }

    /**
     * 下发分料任务清单
     *
     * @param workOrderInfor
     */
    @Override
    public void deliverPickingDetails(WorkOrderInfor workOrderInfor) {
        List<PickingTask> pickingTaskList = pickingTaskRepository.findPickingTaskByWoAndDelete(workOrderInfor.getWo(), 0);
        if (pickingTaskList == null) {
            throw new BeadminException("未找到分料任务单");
        }
        PickingTask pickingTask = null;
        if (pickingTaskList.size() > 0) {
            pickingTask = pickingTaskList.get(0);

            //生产分料实际开始时间
//            PlanStage planStage = planStageRepository.findPlanStageByIdAndDelete(pickingTask.getBatchPlanId(), 0);
//            planStage.setStageStartTime(new Date());
        }
        Date deliveryDate;
        if (pickingTask.getErpOrderNo()!=null) {
            PurchaseOrder purchaseOrder = purchaseOrderRepository.findPurchaseOrderByErpOrderNoAndDelete(pickingTask.getErpOrderNo(), 0);

            if(purchaseOrder==null || purchaseOrder.getDeliveryDate()==null){
                deliveryDate = null;
            }else {
                deliveryDate = purchaseOrder.getDeliveryDate();
            }
        } else {
            deliveryDate = null;
        }


        List<PickingDetails> pickingDetails = new ArrayList<>();
        List<ProductBomOverview> productBomOverviewsByProductCodeAndDelete = productBomOverviewRepository.findProductBomOverviewsByProductCodeAndDelete(workOrderInfor.getBatchProductCode(), 0);

        for (ProductBomOverview productBomOverview : productBomOverviewsByProductCodeAndDelete) {
            PickingDetails pickingDetails1 = new PickingDetails();
            pickingDetails1.setProjectName(pickingTask.getProjectName());
            pickingDetails1.setPickingTaskCode(pickingTask.getPickingTaskCode());
            pickingDetails1.setMaterialSequence(productBomOverview.getBomSequence());
            pickingDetails1.setMaterialCode(productBomOverview.getMaterialCode());
            pickingDetails1.setMaterialName(productBomOverview.getMaterialName());
            pickingDetails1.setChangeStatus(productBomOverview.getChangeStatus());
            pickingDetails1.setPositionNo(productBomOverview.getPositionNo());
            pickingDetails1.setUnit(productBomOverview.getUnit());
            pickingDetails1.setMaterialSpec(productBomOverview.getMaterialSpec());
            pickingDetails1.setMaterialQty(productBomOverview.getMaterialQty());
            pickingDetails1.setUnclaimedQty(productBomOverview.getMaterialQty());
            pickingDetails1.setNotIssuedQty(productBomOverview.getMaterialQty());
            pickingDetails1.setCurrentQty(productBomOverview.getMaterialQty());
            pickingDetails1.setWo(pickingTask.getWo());
            pickingDetails1.setDeliveryDate(deliveryDate);
            pickingDetails1.setPartCode(productBomOverview.getPartCode());
            pickingDetails1.setIsJia(productBomOverview.getIsJia());
            pickingDetails1.setMaterialType(productBomOverview.getMaterialType());
            pickingDetails1.setMaterialClassification(productBomOverview.getMaterialClassification());

            pickingDetails.add(pickingDetails1);
        }
        pickingDetailsRepository.saveAll(pickingDetails);
    }

    /**
     * 下发工单
     *
     * @param batchProductIds
     * @return
     */

    @Override
    // 柜体设计审核通过
    public String issueWorkOrderInforByPage(List<String> batchProductIds) throws ParseException {

        main_processof_issueWorkOrderInforByPage(batchProductIds);

//        if (batchProductIds.size() == 0) throw new BeadminException("以为选择任何柜体");
//
//        List<WorkOrderInfor> workOrderInforList =new ArrayList<>();
//        for (String batchProductId : batchProductIds // 一个柜体一个工单
//        ) {
//
////            BatchProduct product = batchProductRepository.findBatchProductByIdAndDelete(batchProductId,0);
//            BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(batchProductId, 0);
//            if (batchProduct.getBatchPlanId().equals("-1")) throw new BeadminException("该柜体没有批次不能下发工单");
//            BatchPlan plan = batchPlanRepository.findBatchPlanByIdAndDelete(batchProduct.getBatchPlanId(), 0);
//
//            PlanStage stage = batchPlanService.getStageByBatchPlanAndStageName(plan, "生产装配");
////            PlanStage stage2 = batchPlanService.getStageByBatchPlanAndStageName(plan, "生产装配");
//
//
//            MasterPlan masterPlan = masterPlanRepository.findMasterPlanByIdAndDelete(plan.getMasterPlanId(), 0);
//            Info info = infoRepository.findInfoByIdAndDelete(masterPlan.getInfoId(), 0);
//            if (batchProduct.getIsStandard() == 0 && batchProduct.getReviewState() == 0 ) {
//                throw new BeadminException("未上传图纸、BOM或工艺路径");
//            }
//            if (batchProduct.getState() == 2) throw new BeadminException("柜体已经下发！");
////            if (batchProduct.getReviewState() == 1 ) {
////                throw new BeadminException("未审核");
////            }
//
//            WorkOrderInfor workOrderInfor2 = workOrderInforRepository.findWorkOrderInforByBatchProductIdAndDelete(batchProductId, 0);
//            WorkOrderInfor workOrderInfor = new WorkOrderInfor();
//            if (workOrderInfor2 != null) {
//                if (workOrderInfor.getReleaseFlag() == 0) { // 未释放
//                    workOrderInfor = workOrderInfor2;
//
//                } else {
//                    continue;
//                }
//            }
//
////            if (workOrderInfor != null)
//            batchProduct.setState(2);
//
//            workOrderInfor.setBatchProductCode(batchProduct.getProductCode());
//            workOrderInfor.setBatchPlanId(plan.getId());
//            workOrderInfor.setBatchPlanCode(plan.getBatchPlanCode());
//            workOrderInfor.setBatchProductId(batchProductId);
//            workOrderInfor.setBatchProductCode(batchProduct.getProductCode());
//            workOrderInfor.setBatchPlanCode(plan.getBatchPlanCode());
//            workOrderInfor.setBatchDeliveryDate(plan.getBatchDeliveryDate());
//            workOrderInfor.setBatchCount(plan.getBatchCount());
//            workOrderInfor.setBatchPlanId(plan.getId());
//            workOrderInfor.setCurrentBatch(plan.getCurrentBatch());
//            workOrderInfor.setScheduledFlag(1); // 自动
//            workOrderInfor.setInfoId(info.getId());
//            workOrderInfor.setProductType(batchProduct.getProductType());
//            workOrderInfor.setProjectCode(info.getProjectCode());
//            workOrderInfor.setProjectName(info.getProjectName());
//            String wo = serialNumberService.getNextSnByCode(info.getId() + "_WO_Code");
//            if (wo==null) wo = serialNumberService.getNextSnByCode("WorkOrderCode");
//            workOrderInfor.setWo(masterPlan.getMasterPlanCode() + "-" + wo); // 工单号
//            batchProductRepository.save(batchProduct);
//            WorkOrderInfor workOrderInfor1 =  workOrderInforRepository.save(workOrderInfor);
//
//            workOrderInforList.add(workOrderInfor1);
//
//            if (batchProduct.getBopCode() == null) throw new BeadminException("工艺路径为空");
//            List<BopInfo> bopInfoList = bopInfoRepository.findBopInfosByBopCodeOrderBySequenceDesc(batchProduct.getBopCode());
//            if (bopInfoList.size()==0) throw new BeadminException("工序路径中没有任何工序");
//            List<ProductManufactInfor> productManufactInfors = new ArrayList<>();
//
//            ProductManufactInfor before = null;
//            for (int i = 0; i < bopInfoList.size(); i++) {
//                BopInfo bopInfo = bopInfoList.get(i);
//                Process processById = processService.getProcessById(bopInfo.getProcessId());
//
//                ProductManufactInfor p = new ProductManufactInfor();
//                p.setProcessId(processById.getId());
//                p.setProcessCode(processById.getProcessCode());
//                p.setProcessName(processById.getProcessName());
//                p.setIsProductionProcess(processById.getIsProductionProcess());
//                p.setSequence(bopInfo.getSequence());
//                if (batchProduct.getIsStandard()==1) {
//                    StandProduct standProduct = standProductService.getStandProductByCode(batchProduct.getStandardProductCode());
//                    if (standProduct == null) {
//                        throw new BeadminException("未找到标准柜体");
//                    }
//                    StandProductProcessInfo standProductProcessInfo = standProductProcessInfoService.getStandProductProcessInfoByStandProductAndProcess(standProduct, processById);
//                    if (standProductProcessInfo == null) {
//                        throw new BeadminException("未找到标准柜体的该工序");
//                    }
//                    p.setStandManufactWorkhour(standProductProcessInfo.getStandWorkHour());
//                    p.setStandCycle(standProductProcessInfo.getStandCycle());
//                } else {
//                    p.setStandManufactWorkhour(0f);
//                }
//
//                //
//                p.setBatchProductId(batchProduct.getId());
//                p.setBatchProductCode(batchProduct.getProductCode());
//                String wo1 = workOrderInforRepository.findWoByBatchProductIdAndDelete(batchProduct.getId(), 0);
//                p.setWorkOrderInforCode(wo1);
////                if (i==0) {
////                    p.setPlanManufactEndDate(DateUtil.transDateFormat(stage.getStagePlanEndTime()));
////                } else {
////                    p.setPlanManufactEndDate(before.getPlanManufactStartDate());
////                }
////
////                p.setPlanManufactStartDate(DateUtil.computeDate(p.getPlanManufactEndDate(), -1 * p.getStandCycle() * 24));
//
//                before = p;
//                productManufactInfors.add(p);
//            }
//            productManufactInforRepository.saveAll(productManufactInfors);
//
//            // -------------消息通知------------
//            // 审批通过后进行消息通知：技术经理->生产与分料组
//            List<String> cateGoryList = Arrays.asList("生产人员", "生产组长", "生产经理","分料人员","分料组长","分料经理");
//
//            NotifyInfo notifyInfo =new NotifyInfo();
//            notifyInfo.setModuleName("设计管理");
//            notifyInfo.setFuncName("BOM/技术文件审批");
//            notifyInfo.setNotifyDesc("柜体编码为["+batchProduct.getProductCode()+"]--BOM/技术文件审批通过");
//            notifyInfo.setNotifyType("通知");
//            Info projectInfo = infoRepository.findInfoByIdAndDelete(batchProduct.getInfoId(), 0);
//            TeamInfo teaminfo = teamInfoRepository.findTeamInfoByTeamIdAndCategoryAndDelete(projectInfo.getTeamId(), "技术经理", 0);
//            if (teaminfo==null || teaminfo.getUserName()==null){
//                notifyInfo.setSenderName("-");
//            }else{
//                notifyInfo.setSenderName(teaminfo.getUserName());
//                notifyInfo.setSenderId(teaminfo.getUserId());
//            }
//            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH-mm");
//            Date date = new Date();
//            notifyInfo.setSendTime(df.parse(df.format(date)));
//            notifyInfo = notifyInfoRepository.save(notifyInfo);
//
//            List<TeamInfo> teamList = teamInfoRepository.findTeamInfoByTeamIdAndCategoryInAndDelete(projectInfo.getTeamId(), cateGoryList, 0);
//            Set<TeamInfo> sets = new HashSet<>(teamList);
//            for (TeamInfo item: sets){
//                notifyTemplateInfoService.sendNotify(notifyInfo,-1,item.getUserName(),item.getUserId());
//            }
//        }
        // BoM 下发

        // 图纸 下发

        // 生产进度下发

        // 自动排程

        // 手动点击排程按钮
        // 排程也单起一个线程处理
        taskThreadPool.execute(new BaseTask("排程") {
            @Override
            public void doTask() {

                String s = productManufactInforService.autoScheduling(batchProductIds);
            }
        });

        // 生成柜体入场检验单
//        productQualityService.addProductQualityByWos(workOrderInforList);
//        if (!s.equals("")){
//            return "下发成功," + s;
//        }
        return "下发成功";
    }
    @Transactional
    public void main_processof_issueWorkOrderInforByPage(List<String> batchProductIds) throws ParseException {
        if (batchProductIds.size() == 0) throw new BeadminException("以为选择任何柜体");

        List<WorkOrderInfor> workOrderInforList =new ArrayList<>();
        for (String batchProductId : batchProductIds // 一个柜体一个工单
        ) {

//            BatchProduct product = batchProductRepository.findBatchProductByIdAndDelete(batchProductId,0);
            BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(batchProductId, 0);
            if (batchProduct.getBatchPlanId().equals("-1")) throw new BeadminException("该柜体没有批次不能下发工单");
            BatchPlan plan = batchPlanRepository.findBatchPlanByIdAndDelete(batchProduct.getBatchPlanId(), 0);

            PlanStage stage = batchPlanService.getStageByBatchPlanAndStageName(plan, "生产装配");
//            PlanStage stage2 = batchPlanService.getStageByBatchPlanAndStageName(plan, "生产装配");


            MasterPlan masterPlan = masterPlanRepository.findMasterPlanByIdAndDelete(plan.getMasterPlanId(), 0);
            Info info = infoRepository.findInfoByIdAndDelete(masterPlan.getInfoId(), 0);
            if (batchProduct.getIsStandard() == 0 && batchProduct.getReviewState() == 0 ) {
                throw new BeadminException("未上传图纸、BOM或工艺路径");
            }
            if (batchProduct.getState() == 2) throw new BeadminException("柜体已经下发！");
//            if (batchProduct.getReviewState() == 1 ) {
//                throw new BeadminException("未审核");
//            }

            WorkOrderInfor workOrderInfor2 = workOrderInforRepository.findWorkOrderInforByBatchProductIdAndDelete(batchProductId, 0);
            WorkOrderInfor workOrderInfor = new WorkOrderInfor();
            if (workOrderInfor2 != null) {
                if (workOrderInfor.getReleaseFlag() == 0) { // 未释放
                    workOrderInfor = workOrderInfor2;

                } else {
                    continue;
                }
            }

//            if (workOrderInfor != null)
            batchProduct.setState(2);

            workOrderInfor.setBatchProductCode(batchProduct.getProductCode());
            workOrderInfor.setBatchPlanId(plan.getId());
            workOrderInfor.setBatchPlanCode(plan.getBatchPlanCode());
            workOrderInfor.setBatchProductId(batchProductId);
            workOrderInfor.setBatchProductCode(batchProduct.getProductCode());
            workOrderInfor.setBatchPlanCode(plan.getBatchPlanCode());
            workOrderInfor.setBatchDeliveryDate(plan.getBatchDeliveryDate());
            workOrderInfor.setBatchCount(plan.getBatchCount());
            workOrderInfor.setBatchPlanId(plan.getId());
            workOrderInfor.setCurrentBatch(plan.getCurrentBatch());
            workOrderInfor.setScheduledFlag(1); // 未排程
            workOrderInfor.setInfoId(info.getId());
            workOrderInfor.setProductType(batchProduct.getProductType());
            workOrderInfor.setProjectCode(info.getProjectCode());
            workOrderInfor.setProjectName(info.getProjectName());
            String wo = serialNumberService.getNextSnByCode(info.getId() + "_WO_Code");
            if (wo==null) wo = serialNumberService.getNextSnByCode("WorkOrderCode");
            workOrderInfor.setWo(masterPlan.getMasterPlanCode() + "-" + wo); // 工单号
            batchProductRepository.save(batchProduct);
            WorkOrderInfor workOrderInfor1 =  workOrderInforRepository.save(workOrderInfor);

            workOrderInforList.add(workOrderInfor1);

            if (batchProduct.getBopCode() == null) throw new BeadminException("工艺路径为空");
            List<BopInfo> bopInfoList = bopInfoRepository.findBopInfosByBopCodeOrderBySequenceDesc(batchProduct.getBopCode());
            if (bopInfoList.size()==0) throw new BeadminException("工序路径中没有任何工序");
            List<ProductManufactInfor> productManufactInfors = new ArrayList<>();

            ProductManufactInfor before = null;
            for (int i = 0; i < bopInfoList.size(); i++) {
                BopInfo bopInfo = bopInfoList.get(i);
                Process processById = processService.getProcessById(bopInfo.getProcessId());

                ProductManufactInfor p = new ProductManufactInfor();
                p.setProcessId(processById.getId());
                p.setProcessCode(processById.getProcessCode());
                p.setProcessName(processById.getProcessName());
                p.setIsProductionProcess(processById.getIsProductionProcess());
                p.setSequence(bopInfo.getSequence());
                if (batchProduct.getIsStandard()==1) {
                    StandProduct standProduct = standProductService.getStandProductByCode(batchProduct.getStandardProductCode());
                    if (standProduct == null) {
                        throw new BeadminException("未找到标准柜体");
                    }
                    StandProductProcessInfo standProductProcessInfo = standProductProcessInfoService.getStandProductProcessInfoByStandProductAndProcess(standProduct, processById);
                    if (standProductProcessInfo == null) {
                        throw new BeadminException("未找到标准柜体的该工序");
                    }
                    p.setStandManufactWorkhour(standProductProcessInfo.getStandWorkHour());
                    p.setStandCycle(standProductProcessInfo.getStandCycle());
                } else {
                    p.setStandManufactWorkhour(0f);
                }

                //
                p.setBatchProductId(batchProduct.getId());
                p.setBatchProductCode(batchProduct.getProductCode());
                String wo1 = workOrderInforRepository.findWoByBatchProductIdAndDelete(batchProduct.getId(), 0);
                p.setWorkOrderInforCode(wo1);
//                if (i==0) {
//                    p.setPlanManufactEndDate(DateUtil.transDateFormat(stage.getStagePlanEndTime()));
//                } else {
//                    p.setPlanManufactEndDate(before.getPlanManufactStartDate());
//                }
//
//                p.setPlanManufactStartDate(DateUtil.computeDate(p.getPlanManufactEndDate(), -1 * p.getStandCycle() * 24));

                before = p;
                productManufactInfors.add(p);
            }
            productManufactInforRepository.saveAll(productManufactInfors);

            // -------------消息通知------------
            // 审批通过后进行消息通知：技术经理->生产与分料组
            List<String> cateGoryList = Arrays.asList("生产人员", "生产组长", "生产经理","分料人员","分料组长","分料经理");

            NotifyInfo notifyInfo =new NotifyInfo();
            notifyInfo.setModuleName("设计管理");
            notifyInfo.setFuncName("BOM/技术文件审批");
            notifyInfo.setNotifyDesc("柜体编码为["+batchProduct.getProductCode()+"]--BOM/技术文件审批通过");
            notifyInfo.setNotifyType("通知");
            Info projectInfo = infoRepository.findInfoByIdAndDelete(batchProduct.getInfoId(), 0);
            TeamInfo teaminfo = teamInfoRepository.findTeamInfoByTeamIdAndCategoryAndDelete(projectInfo.getTeamId(), "技术经理", 0);
            if (teaminfo==null || teaminfo.getUserName()==null){
                notifyInfo.setSenderName("-");
            }else{
                notifyInfo.setSenderName(teaminfo.getUserName());
                notifyInfo.setSenderId(teaminfo.getUserId());
            }
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH-mm");
            Date date = new Date();
            notifyInfo.setSendTime(df.parse(df.format(date)));
            notifyInfo = notifyInfoRepository.save(notifyInfo);

            List<TeamInfo> teamList = teamInfoRepository.findTeamInfoByTeamIdAndCategoryInAndDelete(projectInfo.getTeamId(), cateGoryList, 0);
            Set<TeamInfo> sets = new HashSet<>(teamList);
            for (TeamInfo item: sets){
                notifyTemplateInfoService.sendNotify(notifyInfo,-1,item.getUserName(),item.getUserId());
            }
        }
        // 生成柜体入场检验单
        productQualityService.addProductQualityByWos(workOrderInforList);
//        if (!s.equals("")){
//            return "下发成功," + s;
//        }
        return;
    }

    public void addMaterialShortage(WorkOrderInfor workOrderInfor){
        String infoId = workOrderInfor.getInfoId();
        Date closeTime = workOrderInfor.getCloseTime();
        List<ProductBomOverview> bomOverviews = productBomOverviewRepository.findProductBomOverviewsByProductCodeAndDelete(workOrderInfor.getBatchProductCode(), 0);
        List<PurchaseOrder> pos = purchaseOrderRepository.findPurchaseOrdersByInfoIdAndDelete(infoId, 0);
        List<MaterialShortage> ans = new LinkedList<>();

        //工单的每个物料
        for (ProductBomOverview bomOverview:bomOverviews) {
            MaterialShortage materialShortage = new MaterialShortage();
            //每个订单
            for (PurchaseOrder p :pos) {
                //订单详情
                List<PurchaseOrderDetail> pds = purchaseOrderDetailRepository.findPurchaseOrderDetailsByPoIdentificationAndDelete(p.getId(), 0);
                for (PurchaseOrderDetail pd:pds) {
                    if(pd.getExpectedDeliveryTime()!=null) {
                        if (pd.getMaterialCode().equals(bomOverview.getMaterialCode()) && pd.getExpectedDeliveryTime().after(closeTime)) {
                            materialShortage.setLackQty(pd.getUndeliveredQty()+materialShortage.getLackQty());
                            materialShortage.setExpectedDeliveryTime(pd.getExpectedDeliveryTime());
                        }
                    }

                }
            }
            if(bomOverview.getMaterialCode()!=null)
                materialShortage.setMaterialCode(bomOverview.getMaterialCode());
            if(bomOverview.getMaterialName()!=null)
                materialShortage.setMaterialName(bomOverview.getMaterialName());
            if(bomOverview.getMaterialType()!=null)
                materialShortage.setMaterialType(bomOverview.getMaterialType());
            if(bomOverview.getMaterialSpec()!=null)
                materialShortage.setMaterialSpec(bomOverview.getMaterialSpec());
            if(bomOverview.getUnit()!=null)
                materialShortage.setUnit(bomOverview.getUnit());
            if(workOrderInfor.getBatchCount()!=null)
                materialShortage.setBatchCount(workOrderInfor.getBatchCount());
            if(workOrderInfor.getCurrentBatch()!=null)
                materialShortage.setCurrentBatch(workOrderInfor.getCurrentBatch());
            if(workOrderInfor.getInfoId()!=null)
                materialShortage.setInfoId(workOrderInfor.getInfoId());
            if(workOrderInfor.getProductName()!=null)
                materialShortage.setProjectName(workOrderInfor.getProductName());
            if(workOrderInfor.getProjectName()!=null)
                materialShortage.setProjectName(workOrderInfor.getProjectName());
            ans.add(materialShortage);
        }

        for (MaterialShortage ms:ans) {
            //save一下
            materialShortageRepository.save(ms);
        }
    }

    /**
     * 关闭工单
     *
     * @param workOrderInfoId
     */
    @SneakyThrows
    @Override
    public void closeWorkOrderInfor(String workOrderInfoId) {
        // 首先查询该工单
        WorkOrderInfor workOrderInfor = workOrderInforService.getWorkOrderInforById(workOrderInfoId);
        if (workOrderInfor == null) {
            throw new BeadminException("未找到该工单");
        }
        // 查询该工单的所有工序
        for (ProductManufactInfor productManufactInfor : productManufactInforRepository.findProductManufactInforsByBatchProductCodeAndDelete(workOrderInfor.getBatchProductCode(), 0)) {
            // 暂停计时并更新产能日历。
            productManufactInforPqService.pauseTimeAndUpdateCap(productManufactInfor);
            // 自检单都设置为完成，  设置未完成， 还是直接删除检验单
            for (InspectionTask inspectionTask : inspectionTaskRepository.findInspectionTasksByProcessIdAndDelete(productManufactInfor.getId(), 0)) {
                inspectionTask.setState(1);
                inspectionTask.setFinishedTime(new Date());
                inspectionTaskRepository.save(inspectionTask);
            }
        }
        // 终检单结束
        for (InspectionTask task : inspectionTaskRepository.findInspectionTaskByWoAndTypeAndDelete(workOrderInfor.getWo(), "终检", 0)) {
            task.setState(1);
            task.setFinishedTime(new Date());
            inspectionTaskRepository.save(task);
        }
        // 工单结束，状态和时间都设置。
        workOrderInfor.setState(2); // 工单完成
        workOrderInfor.setCloseTime(new Date());
        workOrderInforRepository.save(workOrderInfor);
        addMaterialShortage(workOrderInfor);

        //--------------------------------------------
        //能够成功关闭工单
        // 生产经理 发送 关单关闭 通知给  项目成员+生产组长
        NotifyInfo notifyInfo =new NotifyInfo();
        notifyInfo.setModuleName("生产制造");
        notifyInfo.setFuncName("工单关闭");

        String wo=workOrderInfor.getWo();

        notifyInfo.setNotifyDesc("工单号["+wo+"]---工单已被关闭");
        notifyInfo.setNotifyType("通知");

        String infoId = workOrderInfor.getInfoId();
        Info info = infoRepository.findInfoByIdAndDelete(infoId,0);
        if(info == null) return;
        String teamId = info.getTeamId();
        if(teamId==null) return ;
        List<TeamInfo> teamInfoList = teamInfoRepository.findTeamInfoByTeamIdAndDelete(teamId,0);
        TeamInfo projectManager =  teamInfoRepository.findTeamInfoByTeamIdAndCategoryAndDelete(teamId,"生产经理",0);
        String senderName = "-";
        String senderId="-";
        if(projectManager!=null){
            if(projectManager.getUserName()!=null){
                senderName = projectManager.getUserName();
            }
            if(projectManager.getUserId()!=null){
                senderId = projectManager.getUserId();
            }
        }
        notifyInfo.setSenderName(senderName);
        notifyInfo.setSenderId(senderId);
        notifyInfo.setSendTime(workOrderInfor.getUpdateTime());
        notifyInfo = notifyInfoRepository.save(notifyInfo);


        Set<String> st =new HashSet<>();
        for (TeamInfo teamInfo:teamInfoList){
            String receiver = teamInfo.getUserName();
            if(receiver!=null&&!st.contains(receiver)){
                st.add(receiver);
                notifyTemplateInfoService.sendNotify(notifyInfo,-1,receiver,teamInfo.getUserId());
            }
        }
        //放最后
        //--------------------------------------------
    }

}
